#pragma once

#include <grpc++/grpc++.h>
#include "../../proto/rpc.grpc.pb.h"
#include "../action.hpp"
#include "rsp_lease.hpp"
#include "response.hpp"

using grpc::ClientAsyncResponseReader;
using grpc::ClientAsyncReaderWriter;
using etcdserverpb::LeaseGrantResponse;
using etcdserverpb::LeaseRevokeResponse;
using etcdserverpb::LeaseKeepAliveRequest;
using etcdserverpb::LeaseKeepAliveResponse;
using etcdserverpb::LeaseTimeToLiveResponse;

namespace etcdv3 {

//-----------------------------------------------------------------------------
class AsyncLeaseGrantAction : public Action {
public:
    AsyncLeaseGrantAction(const ActionParameters& param);
    AsyncLeaseGrantResponse ParseResponse();
private:
    LeaseGrantResponse reply;
    std::unique_ptr<ClientAsyncResponseReader<LeaseGrantResponse>> reader;
};

//-----------------------------------------------------------------------------
class AsyncLeaseRevokeAction : public Action {
public:
    AsyncLeaseRevokeAction(const ActionParameters& param);
    AsyncLeaseRevokeResponse ParseResponse();
private:
    LeaseRevokeResponse reply;
    std::unique_ptr<ClientAsyncResponseReader<LeaseRevokeResponse>> reader;
};

//-----------------------------------------------------------------------------
class AsyncLeaseKeepAliveAction : public Action {
public:
    AsyncLeaseKeepAliveAction(const ActionParameters& param);
    AsyncLeaseKeepAliveResponse ParseResponse();
    void waitForResponse(std::function<void(const etcd::Response&)> callback);
    void Cancel();
private:
    bool isCancelled;
    grpc::WriteOptions opts;
    LeaseKeepAliveResponse reply;
    etcdserverpb::LeaseKeepAliveRequest request;
    std::unique_ptr<ClientAsyncReaderWriter<LeaseKeepAliveRequest, LeaseKeepAliveResponse>> reader;
};

//-----------------------------------------------------------------------------
class AsyncLeaseTimeToLiveAction : public Action {
public:
    AsyncLeaseTimeToLiveAction(const ActionParameters& param, bool keys = false);
    AsyncLeaseTimeToLiveResponse ParseResponse();
private:
    LeaseTimeToLiveResponse reply;
    std::unique_ptr<ClientAsyncResponseReader<LeaseTimeToLiveResponse>> reader;
};

}
